home *** CD-ROM | disk | FTP | other *** search
/ PC World Interactive 7 / PC World Interactive 7.iso / program / asprog.EXE / WHATCPU.ASM < prev    next >
Assembly Source File  |  1980-01-10  |  9KB  |  261 lines

  1. ;***************************************
  2. ;* WHATCPU.ASM 
  3. ;* Written by Dave M. Walker 
  4. ;* For use with TASM, but shouldn't 
  5. ;* be too hard to change.  
  6. ;* Version 1.1
  7. ;***************************************
  8. ;* Thanks to the author(s) of INFOPLUS, 
  9. ;* Yousuf Khan and David Kirschbaum for 
  10. ;* their contributions. This is released 
  11. ;* into the public domain with no 
  12. ;* reservations, of course.                          
  13. ;***************************************
  14. ;* Returns: 00 for 8088
  15. ;*          01 for 8086
  16. ;*          10 for NEC V20
  17. ;*          11 for NEC V30
  18. ;*          12 for 80188
  19. ;*          13 for 80186
  20. ;*          20 for 80286
  21. ;*          30 for 80386sx
  22. ;*          31 for 80386dx
  23. ;*          40 for 80486 (sx or dx)
  24. ;*          FF for Unknown CPU type
  25. ;***************************************
  26.  
  27.                 IDEAL
  28.                 MODEL   tiny
  29.                 CODESEG
  30.                 ORG     0100h
  31.  
  32. f8088           EQU     00h
  33. f8086           EQU     01h
  34. fV20            EQU     10h
  35. fV30            EQU     11h
  36. f80188          EQU     12h
  37. f80186          EQU     13h
  38. f80286          EQU     20h
  39. f80386SX        EQU     30h
  40. f80386DX        EQU     31h
  41. f80486          EQU     40h
  42. UnkCPU          EQU     0FFh
  43.  
  44. ;*** Test interrupt of multi-prefix string instruction
  45. Start:          sti
  46.                 mov     cx,0FFFFh
  47.                 rep lods [BYTE es:si]
  48.                 jcxz    Test02                  ;If CX == 0, not 8086/8088
  49.  
  50.                 call    PiqCalc                 ;Determine type by PIQ len.
  51.                 cmp     dx,4
  52.                 jne     Test01a
  53.                 mov     bl,f8088
  54.                 jmp     TestDone
  55. Test01a:        cmp     dx,6
  56.                 jne     Test01b
  57.                 mov     bl,f8086
  58.                 jmp     TestDone
  59. Test01b:        mov     bl,UnkCPU
  60.                 jmp     TestDone
  61.  
  62. ;*** Test number of recognized bits used by shift
  63. Test02:         mov     al,0FFh
  64.                 mov     cl,20h
  65.                 shl     al,cl
  66.                 or      al,al
  67.                 jnz     Test03                  ;If AL != 0, not V20/V30
  68.  
  69.                 call    PiqCalc                 ;Determine type by PIQ len.
  70.                 cmp     dx,4
  71.                 jne     Test02a
  72.                 mov     bl,fV20
  73.                 jmp     TestDone
  74. Test02a:        cmp     dx,6
  75.                 jne     Test02b
  76.                 mov     bl,fV30
  77.                 jmp     TestDone
  78. Test02b:        mov     bl,UnkCPU
  79.                 jmp     TestDone
  80.  
  81. ;*** Test order of write/decrement by PUSH SP
  82. Test03:         push    sp
  83.                 pop     ax
  84.                 cmp     ax,sp
  85.                 je      SHORT Test04            ;If AX == SP, not 80186/80188
  86.  
  87.                 call    PiqCalc                 ;Determine type by PIQ len.
  88.                 cmp     dx,4
  89.                 jne     Test03a
  90.                 mov     bl,f80188
  91.                 jmp     TestDone
  92. Test03a:        cmp     dx,6
  93.                 jne     Test03b
  94.                 mov     bl,f80186
  95.                 jmp     TestDone
  96. Test03b:        mov     bl,UnkCPU
  97.                 jmp     TestDone
  98.  
  99. ;*** Test high nybble of FLAGS register (80286 remains 0's)
  100. Test04:         pushf
  101.                 pop     ax
  102.                 or      ah,0F0h
  103.                 push    ax
  104.                 popf
  105.                 pushf
  106.                 pop     ax
  107.                 test    ah,0F0h
  108.                 jnz     Test05                  ;If FLAGS changes, not 80286
  109.  
  110.                 mov     bl,f80286
  111.                 jmp     TestDone
  112.  
  113. ;*** Test CR0 register bit 4 (386SX won't allow 1)
  114. Test05:         P386
  115.                 mov     eax,cr0
  116.                 mov     ebx,eax                 ;Original CR0 into EBX
  117.                 or      al,10h                  ;Set bit
  118.                 mov     cr0,eax                 ;Store it
  119.                 mov     eax,cr0                 ;Read it back
  120.                 mov     cr0,ebx                 ;Restore CR0
  121.                 test    al,10h                  ;Did it set?
  122.                 jnz     Test06                  ;Go if not 386SX
  123.  
  124.                 mov     bl,f80386SX
  125.                 jmp     TestDone
  126.  
  127. ;*** Test AC bit in EFLAGS (386DX won't change)
  128. Test06:         mov     ecx,esp                 ;Original ESP in ECX
  129.                 pushfd                          ;Original EFLAGS in EBX
  130.                 pop     ebx
  131.                 and     esp,not 3               ;Align stack to prevent 486
  132.                                                 ;  fault when AC is flipped
  133.                 mov     eax,ebx                 ;EFLAGS => EAX
  134.                 xor     eax,40000h              ;Flip AC flag
  135.                 push    eax                     ;Store it
  136.                 popfd
  137.                 pushfd                          ;Read it back
  138.                 pop     eax
  139.                 push    ebx                     ;Restore EFLAGS
  140.                 popfd
  141.                 mov     esp,ecx                 ;Restore ESP
  142.                 cmp     eax,ebx                 ;Compare old/new AC bits
  143.                 jne     Test07                  ;If AC changes, not 386
  144.  
  145.                 mov     bl,f80386DX
  146.                 jmp     SHORT TestDone
  147.  
  148. Test07:         mov     bl,f80486               ;Until the Pentium appears...
  149.  
  150. TestDone:       call    PrintCPU
  151.                 call    PrintPiq
  152.  
  153. ;*** At this point, BL=CPU type, DL=PIQlen
  154.                 mov     al,bl
  155.                 mov     ah,4Ch
  156.                 int     21h
  157.  
  158. ;***************************************
  159. ;* On exit:
  160. ;*   DX = Length of PIQ (0..64)
  161. ;*   AL, CX, DI destroyed
  162. ;*   Assumes ES = CS
  163. ;***************************************
  164. PROC            PiqCalc
  165.  
  166. MaxPIQ          EQU     64                      ;Maximum PIQ to check
  167. OpIncDX         EQU     42h
  168. OpNop           EQU     90h
  169.  
  170.                 jmp     PiqCalcEntry
  171.  
  172.                 ALIGN   16                      ;PIQ must start on para.
  173.  
  174. PiqStart:       rep stosb
  175. Piq:            db      MaxPIQ dup (OpIncDX)    ;Original code is INC DX
  176.  
  177.                 ALIGN   2
  178.                 sti
  179.                 add     dx,2                    ;Adjust for 'REP STOSB'
  180.                 ret
  181.  
  182. PiqCalcEntry:   cld
  183.                 xor     dx,dx                   ;Reset PIQ counter
  184.                 mov     cx,MaxPIQ               ;Reset PIQ to "INC DX"s
  185.                 mov     di,OFFSET Piq
  186.                 mov     al,OpIncDX
  187.                 rep stosb
  188.                 mov     cx,MaxPIQ
  189.                 mov     di,OFFSET Piq
  190.                 mov     al,OpNop                ;Opcode for NOP
  191.                 cli
  192.                 jmp     PiqStart
  193.  
  194. ENDP
  195.  
  196. PROC            PrintCPU
  197.                 mov     dx,OFFSET CPUa$         ;Print start of message
  198.                 mov     ah,9
  199.                 int     21h
  200.  
  201.                 mov     si,OFFSET CPUb$         ;Search for proper string
  202. PrintCPU_10:    cmp     bl,[si]
  203.                 je      PrintCPU_90
  204.                 add     si,9
  205.                 jmp     PrintCPU_10
  206.  
  207. PrintCPU_90:    inc     si                      ;Print string
  208.                 mov     dx,si
  209.                 mov     ah,9
  210.                 int     21h
  211.                 mov     dl,13                   ;Print CR/LF
  212.                 mov     ah,2
  213.                 int     21h
  214.                 mov     dl,10
  215.                 mov     ah,2
  216.                 int     21h
  217.                 ret
  218.  
  219. CPUa$           db      'CPU type: $'
  220. CPUb$           db      00h,'8088$   '
  221.                 db      01h,'8086$   '
  222.                 db      10h,'NEC V20$'
  223.                 db      11h,'NEC V30$'
  224.                 db      12h,'80188$  '
  225.                 db      13h,'80186$  '
  226.                 db      20h,'80286$  '
  227.                 db      30h,'80386SX$'
  228.                 db      31h,'80386DX$'
  229.                 db      40h,'80486$  '
  230.                 db      0FFh,'Unknown$'
  231. ENDP
  232.  
  233. PROC            PrintPiq
  234.                 call    PiqCalc
  235.                 push    dx
  236.                 mov     ax,dx                   ;Ensure PIQlen is valid
  237.                 cmp     ax,MaxPIQ
  238.                 ja      PiqErr
  239.                 mov     dl,10                   ;Convert PIQlen to ASCII
  240.                 div     dl
  241.                 add     ax,3030h
  242.                 mov     [PiqStore],al           ;Store result
  243.                 mov     [PiqStore+1],ah
  244.                 mov     dx,OFFSET Piq$          ;Print result
  245.                 mov     ah,9
  246.                 int     21h
  247.                 pop     dx
  248.                 ret
  249.  
  250. PiqErr:         mov     dx,OFFSET PiqErr$       ;Print error message
  251.                 mov     ah,9
  252.                 int     21h
  253.                 ret
  254.  
  255. Piq$            db      'PIQ = '
  256. PiqStore        db      '?? Bytes',13,10,'$'
  257. PiqErr$         db      'PIQ length invalid!',13,10,'$'
  258. ENDP
  259.  
  260.                 END     Start
  261.